//#include <cstdint>
#include <cstdio>

#include <netinet/in.h>

#include "messages.h"
#include "server_serialize.h"

//debug mode,prints the packages received

#ifdef DEBUG
bool debug_mode = true;
#else
bool debug_mode = false;
#endif

//in case of error, print message and exit
void error(const char *msg)
{
  printf("###SERVER ERROR### %s\n",msg);
  exit(1);
}

// prepare the message to send
char *encapsulate(uint16_t length, char *message)
{
	char *ret = new char[length + 2];
	int bla = htons(length);//network order
	memcpy(ret, &bla, 2);
	memcpy(ret+2, message, length);
	return ret;
}

//calculate the length of the message
int msg_length(char *message)
{
	uint16_t length_nbo;
	memcpy(&length_nbo, message, 2);
	return ntohs(length_nbo);//network order
	
}

// send the SL type messages
char *serializeSL(MessageSLMessage *msg)
{
	char serial[65555];
	uint8_t type = msg->type;
	memcpy(serial, &type, 1);
	switch (msg->type)
	{
	case SL_ASSOCIATE_OK:
		type = msg->type;
		memcpy(serial, &type, 1);
		return encapsulate(1, serial);
	
	case SL_DEASSOCIATE_OK:
		type = msg->type;
		memcpy(serial, &type, 1);
		return encapsulate(1, serial);
	
	case SL_MESSAGE:
		type = msg->type;
		memcpy(serial, &type, 1);
		strcpy(serial+1, msg->message);
		return encapsulate(2+strlen(msg->message), serial);
	}
	error("error serializing SL, wrong Message type");
	return 0;
}

// send the SC type messages
char *serializeSC(MessageSC *msg)
{

	char serial[1];
	uint8_t type = msg->type;
	memcpy(serial, &type, 1);
	return encapsulate(1, serial);

}

// receives LS message
int deserializeLS(char *serial)
{
	uint8_t length_nbo;
	memcpy(&length_nbo, serial, 1);
	return length_nbo;
}
//receives CS message
int deserializeCS(char *serial)
{
	uint8_t length_nbo;
	memcpy(&length_nbo, serial, 1);
	return length_nbo;
}

//debug function, print the package in hexa
void print_in_hexa(char *s,int inic,int tam)
{
  for(int i=0;i<tam;i++)
    printf(" %x",s[i+inic]);
  
}

//waits until have received all the package
bool my_read(int file,char* buf,int tam)
{
  int total = 0;
  int tmp;
  while(total<tam)
   {
     tmp = read(file,buf+total,tam-total);
     if(tmp<=0)//error!
      	 return false;
     //if debug, print the message
     if(debug_mode)
       {
	 printf("RECEIVING: file descriptor:%d msg:",file);
	 print_in_hexa(buf,total,tmp);
	 printf("\n");
       }
     total+=tmp;
   }
  return true;
}
//waits until have send all the package
bool my_write(int file,char *buf,int tam)
{
  int total = 0;
  int tmp;
  while(total<tam)
    {
      tmp = write(file,buf+total,tam-total);
      if(tmp<=0)//error!
	return false;
      //if debug print message
      if(debug_mode)
	{
	  printf("SENDING: file descriptor:%d msg:", file);
	  print_in_hexa(buf,total,tmp);
	  printf("\n");
	}
      
      total+=tmp;
    }
  return true;
}
